-module(pngparse2).
-compile(export_all).

get_all_pngs() ->
  {ok, AllFiles} = file:list_dir("."),
  AllPngs = lists:filter(fun is_png/1, AllFiles).

get_all_pngs_nested() ->
  AllPngs = filelib:fold_files(".", ".*", true, fun(Filename, Files) -> add_if_png(Filename, Files) end, []),
  AllPngs.

add_if_png(Filename, Files) ->
  case is_png(Filename) of
    true -> 
      [{png, Filename} | Files];
    false ->
      Files
  end.

is_png(Filename) ->
  Parts = string:tokens(Filename, "."),
  Extension = string:to_lower(lists:last(Parts)),
  case Extension of
    "png" ->
      true;
    _ ->
      false
  end.

read_png(Filename) ->
  %% open the png, reading in 8 bytes.
  case file:open(Filename, [read, binary]) of
    {ok, IODevice} ->
      process_png(IODevice),
      file:close(IODevice);
    {error, Reason} ->
      {error, Reason}
  end.

process_png(IODevice) ->
  %% PNG always starts with 137 80 78 71 13 10 26 10 (decimal)
  %% make sure this file has the correct header
  case file:read(IODevice, 8) of 
    {ok, <<137,80,78,71,13,10,26,10>>} ->
      start_chunk(IODevice);
    Error ->
      {error, Error}
  end.

start_chunk(IODevice) ->
  %% Each piece is 32 bits long. We're matching to 8 bytes of data.
  {ok, <<Length:32, ChunkType:4/binary>>} = file:read(IODevice,8),
%%  io:format("ChunkType: ~p~n", [ChunkType]),
  {ok, ChunkData} = file:read(IODevice, Length),
  %% Skip past the CRC data
  file:read(IODevice, 4),
  process_chunk(IODevice, ChunkType, ChunkData).

process_chunk(IODevice, <<"IHDR">>, ChunkData) ->
  <<Width:32, Height:32, Rest/binary>> = ChunkData,
  io:format("Width: ~p~nHeight: ~p~n", [Width, Height]),
  start_chunk(IODevice);

process_chunk(IODevice, <<"tEXt">>, ChunkData) ->
  <<"Comment", 0, Comment/binary>> = ChunkData,
  io:format("Comment: ~p~n", [binary_to_list(Comment)]),
  start_chunk(IODevice);

process_chunk(IODevice, <<"IEND">>, _) ->
  io:format("Finished processing image.~n", []);

process_chunk(IODevice, _, _) ->
  start_chunk(IODevice).
